﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SuperMap.Data;
using System.IO;
using SuperMap.Analyst.SpatialAnalyst;
using System.Threading;
using SuperMap.Desktop;

namespace SuperMap.HB.ThemeWork
{
    public partial class InterpolateMapControl : UserControl
    {
        private const string m_DataSourceName = "基础数据";
        private Datasource m_DataSource = Desktop.Application.ActiveApplication.Workspace.Datasources[m_DataSourceName];

        private IDWInterpolateRegionInfo m_IDWInfo;
        private string m_ClipDatasetName;
        private Geometry m_AllRegion = new GeoRegion();

        public InterpolateMapControl()
        {
            InitializeComponent();

            groupBox1.Paint += groupBox_Paint;
            groupBox3.Paint += groupBox_Paint;
            groupBox4.Paint += groupBox_Paint;
        }

        private void groupBox_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                GroupBox gBox = (GroupBox)sender;

                e.Graphics.Clear(gBox.BackColor);
                e.Graphics.DrawString(gBox.Text, gBox.Font, Brushes.Black, 10, 1);
                var vSize = e.Graphics.MeasureString(gBox.Text, gBox.Font);
                e.Graphics.DrawLine(Pens.Black, 1, vSize.Height / 2, 8, vSize.Height / 2);
                e.Graphics.DrawLine(Pens.Black, vSize.Width + 8, vSize.Height / 2, gBox.Width - 2, vSize.Height / 2);
                e.Graphics.DrawLine(Pens.Black, 1, vSize.Height / 2, 1, gBox.Height - 2);
                e.Graphics.DrawLine(Pens.Black, 1, gBox.Height - 2, gBox.Width - 2, gBox.Height - 2);
                e.Graphics.DrawLine(Pens.Black, gBox.Width - 2, vSize.Height / 2, gBox.Width - 2, gBox.Height - 2);
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void rdo_Select_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (rdo_Select.Checked)
                {
                    cmb_SelectData.Visible = true;
                    txt_FilePath.Visible = false;
                    btn_SelectPath.Visible = false;
                }
                if (rdo_New.Checked)
                {
                    cmb_SelectData.Visible = false;
                    txt_FilePath.Visible = true;
                    btn_SelectPath.Visible = true;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void rdo_KdTreeFixedCount_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (rdo_KdTreeFixedCount.Checked)
                {
                    lbl_Param1.Text = "最大半径：";
                    lbl_Param2.Text = "查找点数：";
                    txt_Param1.Text = "0";
                    txt_Param2.Text = "12";
                    m_IDWInfo.SearchMode = Analyst.SpatialAnalyst.SearchMode.KdTreeFixedCount;
                }
                if (rdo_KdTreeFixedRadius.Checked)
                {
                    lbl_Param1.Text = "查找半径：";
                    lbl_Param2.Text = "最小点数：";
                    txt_Param1.Text = "2";
                    txt_Param2.Text = "5";
                    m_IDWInfo.SearchMode = Analyst.SpatialAnalyst.SearchMode.KdTreeFixedRadius;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void rdo_SelectClipData_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                if (rdo_SelectClipData.Checked)
                {
                    cmb_SelectClipData.Visible = true;
                    txt_ClipFilePath.Visible = false;
                    btn_SelectClipFile.Visible = false;
                }
                if (rdo_ImportClipData.Checked)
                {
                    cmb_SelectClipData.Visible = false;
                    txt_ClipFilePath.Visible = true;
                    btn_SelectClipFile.Visible = true;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void InterpolateMapControl_Load(object sender, EventArgs e)
        {
            try
            {
                m_IDWInfo = new IDWInterpolateRegionInfo();
                cmb_SelectData.Items.Clear();
                cmb_SelectClipData.Items.Clear();
                foreach (Dataset dt in m_DataSource.Datasets)
                {
                    if (dt.Type == DatasetType.Point)
                    {
                        cmb_SelectData.Items.Add(dt.Name);
                    }
                    if (dt.Type == DatasetType.Region)
                    {
                        cmb_SelectClipData.Items.Add(dt.Name);
                    }
                }
                if (cmb_SelectData.Items.Count > 0)
                {
                    cmb_SelectData.SelectedIndex = 0;
                }
                if (cmb_SelectClipData.Items.Count > 0)
                {
                    cmb_SelectClipData.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void cmb_SelectData_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                string dtName = cmb_SelectData.Text;
                m_IDWInfo.DatasetName = dtName;
                cmb_SelectField.Items.Clear();
                DatasetVector dtv = m_DataSource.Datasets[dtName] as DatasetVector;
                txt_Resolution.Text = ((dtv.Bounds.Top - dtv.Bounds.Bottom) / 1000).ToString();
                foreach (FieldInfo field in dtv.FieldInfos)
                {
                    if (!field.Name.ToLower().Contains("sm"))
                    {
                        cmb_SelectField.Items.Add(field.Name);
                    }
                }
                if (cmb_SelectField.Items.Count > 0)
                {
                    cmb_SelectField.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void btn_SelectPath_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog open = new OpenFileDialog
                {
                    Filter = "Shapefile文件|*.shp",
                    Multiselect = false
                };
                if (open.ShowDialog() == DialogResult.OK)
                {
                    txt_FilePath.Text = open.FileName;
                    string datasetName = m_DataSource.Datasets.GetAvailableDatasetName((new FileInfo(txt_FilePath.Text)).Name.Split('.')[0]);
                    m_IDWInfo.DatasetName = datasetName;
                    ImportDataManager import = new ImportDataManager();
                    import.OnImportFinished += Import_OnImportFinished;
                    import.Import(m_DataSourceName, datasetName, open.FileName);
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void Import_OnImportFinished(object sender, EventArgs e)
        {
            try
            {
                cmb_SelectField.Items.Clear();
                DatasetVector dtv = m_DataSource.Datasets[m_IDWInfo.DatasetName] as DatasetVector;
                txt_Resolution.Text = ((dtv.Bounds.Top - dtv.Bounds.Bottom) / 1000).ToString();
                foreach (FieldInfo info in dtv.FieldInfos)
                {
                    if (!info.Name.ToLower().Contains("sm"))
                    {
                        cmb_SelectField.Items.Add(info.Name);
                    }
                }
                if (cmb_SelectField.Items.Count > 0)
                {
                    cmb_SelectField.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void cmb_SelectField_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                m_IDWInfo.ThemeFieldName = cmb_SelectField.Text;
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void cmb_SelectClipData_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                m_ClipDatasetName = cmb_SelectClipData.Text;
                DatasetVector dtv = m_DataSource.Datasets[m_ClipDatasetName] as DatasetVector;
                cmb_ShowField.Items.Clear();
                foreach (FieldInfo info in dtv.FieldInfos)
                {
                    if (!info.Name.ToLower().Contains("sm"))
                    {
                        cmb_ShowField.Items.Add(info.Name);
                    }
                }
                if (cmb_ShowField.Items.Count > 0)
                {
                    cmb_ShowField.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void btn_SelectClipFile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog open = new OpenFileDialog
                {
                    Filter = "Shapefile文件（.shp）|*.shp",
                    Multiselect = false
                };
                if (open.ShowDialog() == DialogResult.OK)
                {
                    txt_ClipFilePath.Text = open.FileName;
                    m_ClipDatasetName = m_DataSource.Datasets.GetAvailableDatasetName((new FileInfo(txt_ClipFilePath.Text)).Name.Split('.')[0]);
                    ImportDataManager import = new ImportDataManager();
                    import.Import(m_DataSourceName, m_ClipDatasetName, open.FileName);
                    import.OnImportFinished += Import_OnImportFinished2;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void Import_OnImportFinished2(object sender, EventArgs e)
        {
            try
            {
                cmb_ShowField.Items.Clear();
                DatasetVector dtv = m_DataSource.Datasets[m_ClipDatasetName] as DatasetVector;
                foreach (FieldInfo info in dtv.FieldInfos)
                {
                    if (!info.Name.ToLower().Contains("sm"))
                    {
                        cmb_ShowField.Items.Add(info.Name);
                    }
                }
                if (cmb_ShowField.Items.Count > 0)
                {
                    cmb_ShowField.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void cmb_ShowField_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                Recordset objRt = null;
                try
                {
                    string fileName = cmb_ShowField.Text;
                    DatasetVector dtv = m_DataSource.Datasets[m_ClipDatasetName] as DatasetVector;
                    objRt = dtv.GetRecordset(false, CursorType.Static);
                    objRt.MoveFirst();
                    cmb_ClipRegion.Items.Clear();
                    cmb_ClipRegion.Items.Add("全部");
                    while (!objRt.IsEOF)
                    {
                        cmb_ClipRegion.Items.Add(objRt.GetFieldValue(fileName).ToString());
                        m_AllRegion = Geometrist.Union(m_AllRegion, objRt.GetGeometry());

                        objRt.MoveNext();
                    }
                    if (cmb_ClipRegion.Items.Count > 0)
                    {
                        cmb_ClipRegion.SelectedIndex = 0;
                        m_IDWInfo.ClipRegion = m_AllRegion as GeoRegion;
                    }
                }
                catch (Exception ex)
                {
                    Log.OutputBox(ex);
                }
                finally
                {
                    if (objRt != null)
                    {
                        objRt.Close();
                        objRt.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void cmb_ClipRegion_SelectedIndexChanged(object sender, EventArgs e)
        {
            Recordset objRt = null;
            try
            {
                string fileName = cmb_ShowField.Text;
                string value = cmb_ClipRegion.Text;
                DatasetVector dtv = m_DataSource.Datasets[m_ClipDatasetName] as DatasetVector;
                objRt = dtv.GetRecordset(false, CursorType.Static);
                while (!objRt.IsEOF)
                {
                    if (objRt.GetFieldValue(fileName).ToString().Equals(value))
                    {
                        m_IDWInfo.ClipRegion = objRt.GetGeometry() as GeoRegion;
                        break;
                    }

                    objRt.MoveNext();
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
            finally
            {
                if(objRt!= null)
                {
                    objRt.Close();
                    objRt.Dispose();
                }
            }
        }

        private void btn_OK_Click(object sender, EventArgs e)
        {
            try
            {
                MessageTip tip = new MessageTip();
                tip.ShowTip();
                InterpolationIDWParameter para = new InterpolationIDWParameter
                {
                    Bounds = m_IDWInfo.ClipRegion.Bounds,
                    ExpectedCount = Convert.ToInt32(txt_Param2.Text.Trim()),
                    Power = Convert.ToInt32(txt_Power.Text.Trim()),
                    Resolution = Convert.ToDouble(txt_Resolution.Text.Trim()),
                    SearchMode = m_IDWInfo.SearchMode,
                    SearchRadius = Convert.ToDouble(txt_Param1.Text.Trim())
                };
                DatasetGrid datasetGrid = Interpolator.Interpolate(para,
                    (m_DataSource.Datasets[m_IDWInfo.DatasetName] as DatasetVector),
                    m_IDWInfo.ThemeFieldName, 1, m_DataSource, m_IDWInfo.ThemeFieldName + "_Grid",
                    PixelFormat.Bit32);
                string datasetName = m_DataSource.Datasets.GetAvailableDatasetName(m_IDWInfo.ThemeFieldName + "_clip");
                Dataset dataset = RasterClip.Clip(datasetGrid, m_IDWInfo.ClipRegion, true, true, m_DataSource, datasetName);
                (dataset as DatasetGrid).BuildPyramid();
                
                if (dataset != null)
                {
                    m_DataSource.Datasets.Delete(m_IDWInfo.ThemeFieldName + "_Grid");
                }

                Desktop.Application.ActiveApplication.MainForm.FormManager.CloseAll(false);

                IFormMap formMap = Desktop.Application.ActiveApplication.CreateMapWindow();
                Desktop.Application.ActiveApplication.MainForm.MdiTabGroupManager.FindMdiTab(formMap.MapControl.ParentForm).Text = txt_MapName.Text.Trim();
                formMap.MapControl.Map.Name= txt_MapName.Text.Trim();
                formMap.MapControl.Map.Layers.Add(dataset, true);
                formMap.MapControl.Map.ViewEntire();
                bool exist = false;
                foreach (string map in Desktop.Application.ActiveApplication.Workspace.Maps)
                {
                    if (map.Equals(txt_MapName.Text.Trim()))
                    {
                        exist = true;
                        break;
                    }
                }
                if (exist)
                {
                    Desktop.Application.ActiveApplication.Workspace.Maps.SetMapXML(txt_MapName.Text.Trim(), formMap.MapControl.Map.ToXML());
                }
                else
                {
                    Desktop.Application.ActiveApplication.Workspace.Maps.Add(txt_MapName.Text.Trim(), formMap.MapControl.Map.ToXML());
                }
                if (Desktop.Application.ActiveApplication.Workspace.Save())
                {
                    tip.HideTip();
                    Desktop.Application.ActiveApplication.MessageBox.Show("保存成功！");
                }
                else
                {
                    tip.HideTip();
                    Desktop.Application.ActiveApplication.MessageBox.Show("保存失败！");
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void chk_EnableReclass_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                cmb_SelectReclassData.Enabled = chk_EnableReclass.Checked;
                rdo_LeftOpen.Enabled = chk_EnableReclass.Checked;
                rdo_RightOpen.Enabled = chk_EnableReclass.Checked;
                dgv_Reclass.Enabled = chk_EnableReclass.Checked;
                btn_ReclassOK.Enabled = chk_EnableReclass.Checked;
                txt_Count.Enabled = chk_EnableReclass.Checked;
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (tabControl.SelectedIndex == 1)
                {
                    cmb_SelectReclassData.Items.Clear();
                    foreach (Dataset dt in m_DataSource.Datasets)
                    {
                        if (dt.Type == DatasetType.Grid)
                        {
                            cmb_SelectReclassData.Items.Add(dt.Name);
                        }
                    }
                    if (cmb_SelectReclassData.Items.Count > 0)
                    {
                        cmb_SelectReclassData.SelectedIndex = 0;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void txt_Count_TextChanged(object sender, EventArgs e)
        {
            try
            {
                CalculateReclass();
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void cmb_SelectReclassData_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                CalculateReclass();
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void CalculateReclass()
        {
            try
            {
                if (string.IsNullOrEmpty(txt_Count.Text) || string.IsNullOrEmpty(cmb_SelectReclassData.Text))
                {
                    return;
                }
                DatasetGrid dataGrid = m_DataSource.Datasets[cmb_SelectReclassData.Text] as DatasetGrid;
                double length = (dataGrid.MaxValue - dataGrid.MinValue) / Convert.ToInt32(txt_Count.Text.Trim());
                dgv_Reclass.Rows.Clear();
                for(int i = 0; i < Convert.ToInt32(txt_Count.Text.Trim()); i++)
                {
                    double dMin = dataGrid.MinValue + (i * length);
                    double dMax = dMin + length;
                    DataGridViewRow row = new DataGridViewRow();
                    row.Cells.Add(new DataGridViewTextBoxCell { Value = dMin.ToString("0.00"), Tag = dMin });
                    row.Cells.Add(new DataGridViewTextBoxCell { Value = dMax.ToString("0.00"), Tag = dMax });
                    row.Cells.Add(new DataGridViewTextBoxCell { Value = (i + 1).ToString() });
                    dgv_Reclass.Rows.Add(row);
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }

        private void btn_ReclassOK_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(txt_Count.Text) || string.IsNullOrEmpty(cmb_SelectReclassData.Text))
                {
                    return;
                }
                MessageTip tip = new MessageTip();
                tip.ShowTip();
                ReclassSegment[] segments = new ReclassSegment[dgv_Reclass.Rows.Count];
                for(int i = 0; i < dgv_Reclass.Rows.Count; i++)
                {
                    ReclassSegment segment = new ReclassSegment
                    {
                        StartValue = Convert.ToDouble(dgv_Reclass.Rows[i].Cells[0].Tag),
                        EndValue = Convert.ToDouble(dgv_Reclass.Rows[i].Cells[1].Tag),
                        NewValue = Convert.ToDouble(dgv_Reclass.Rows[i].Cells[2].Value)
                    };
                    if (rdo_LeftOpen.Checked)
                    {
                        segment.SegmentType = ReclassSegmentType.OpenClose;
                    }
                    else if (rdo_RightOpen.Checked)
                    {
                        segment.SegmentType = ReclassSegmentType.CloseOpen;
                    }
                    segments[i] = segment;
                }
                ReclassMappingTable table = new ReclassMappingTable
                {
                    ReclassType = ReclassType.Range,
                    Segments = segments
                };
                DatasetGrid dataGrid = m_DataSource.Datasets[cmb_SelectReclassData.Text] as DatasetGrid;
                DatasetGrid dgResult = GeneralizeAnalyst.Reclass(dataGrid, table, ReclassPixelFormat.Bit32, m_DataSource, m_DataSource.Datasets.GetAvailableDatasetName(dataGrid.Name.Replace("clip", "_reclass")));
                dgResult.BuildPyramid();

                IFormMap formMap = Desktop.Application.ActiveApplication.CreateMapWindow();
                Desktop.Application.ActiveApplication.MainForm.MdiTabGroupManager.FindMdiTab(formMap.MapControl.ParentForm).Text = dgResult.Name;
                formMap.MapControl.Map.Name = dgResult.Name;
                formMap.MapControl.Map.Layers.Add(dgResult, true);
                formMap.MapControl.Map.ViewEntire();
                bool exist = false;
                foreach (string map in Desktop.Application.ActiveApplication.Workspace.Maps)
                {
                    if (map.Equals(dgResult.Name))
                    {
                        exist = true;
                        break;
                    }
                }
                if (exist)
                {
                    Desktop.Application.ActiveApplication.Workspace.Maps.SetMapXML(dgResult.Name, formMap.MapControl.Map.ToXML());
                }
                else
                {
                    Desktop.Application.ActiveApplication.Workspace.Maps.Add(dgResult.Name, formMap.MapControl.Map.ToXML());
                }
                if (Desktop.Application.ActiveApplication.Workspace.Save())
                {
                    tip.HideTip();
                    Desktop.Application.ActiveApplication.MessageBox.Show("保存成功！");
                }
                else
                {
                    tip.HideTip();
                    Desktop.Application.ActiveApplication.MessageBox.Show("保存失败！");
                }
            }
            catch (Exception ex)
            {
                Log.OutputBox(ex);
            }
        }
    }
}
